package com.hubujun.driverlicense.util;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.text.Spanned;
import android.text.util.Linkify;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


import com.hubujun.driverlicense.ApplicationContext;
import com.hubujun.driverlicense.R;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import java.lang.reflect.Field;

public class ViewUtils {

    public static final float VIEW_EXPOSED_ASPECT = 0.8F;

    private static final Paint paint = new Paint();
    private static int mDisplayHeight;
    private static int mDisplayWidth;
    public static int mP72 = 72;

    public static float mDesity;

    static {
        mDesity = ApplicationContext.getContext().getResources().getDisplayMetrics().density;
    }

    /**
     * dip换算成像素数量
     *
     * @param context
     * @param dip
     * @return
     */
    public static int
    dipToPx(Context context, float dip) {
        return roundUp(dip * context.getResources().getDisplayMetrics().density);
    }

    public static int pxToSp(Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }

    public static void dip72ToPx(Context context) {
        mP72 = roundUp(72 * context.getResources().getDisplayMetrics().density);
    }

    /**
     * 获取app 全局配置的左右边距 (默认左右边距是相等的)
     * @return 返回单位 像素
     */
    public static  int getGeneralMargin(Context context){
        if(context == null){
            return 0;
        }

        int generalMargin = context.getResources().getDimensionPixelSize(R.dimen.general_margin_left);

        Ln.d("yks getGeneralMargin = %s", generalMargin);

        return generalMargin;

    }

    /**
     * 获得activity内部的Root View
     *
     * @param activity
     * @return
     */
    public static View getContentView(Activity activity) {
        return ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
    }

    public static int getDisplayHeight(Context context) {
        if (mDisplayHeight <= 0) {
            mDisplayHeight = context.getResources().getDisplayMetrics().heightPixels;
        }
        return mDisplayHeight;
    }

    public static int getDisplayWidth(Context context) {
        if (mDisplayWidth <= 0) {
            mDisplayWidth = context.getResources().getDisplayMetrics().widthPixels;
        }
        return mDisplayWidth;
    }

    public static float getDisplayDensity(Context context) {
        return context.getResources().getDisplayMetrics().density;
    }

    public static int getStatusBarHeight(Context context) {
        Class<?> c = null;
        Object obj = null;
        Field field = null;
        int x = 0;
        try {
            c = Class.forName("com.android.internal.R$dimen");
            obj = c.newInstance();
            field = c.getField("status_bar_height");
            x = Integer.parseInt(field.get(obj).toString());
            return context.getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            Ln.e(e);
        }
        return 0;
    }

    public static int getTextViewWidth(TextView textview) {
        String s;
        CharSequence chars = textview.getText();
        if (chars instanceof Spanned)
            s = Html.toHtml((Spanned) chars).trim();
        else
            s = (String) chars;
        String[] as = s.replaceAll("<(?!\\/?b(?=>|\\s.*>))\\/?.*?>", "").split("(<b>)|(</b>)");
        int i = 0;
        for (int j = 0; j < as.length; ++j) {
            paint.setTextSize(textview.getTextSize());
            if (j % 2 == 0)
                paint.setTypeface(Typeface.DEFAULT);
            else
                paint.setTypeface(Typeface.DEFAULT_BOLD);
            String s1 = as[j];
            String s2 = (new StringBuilder()).append("x").append(s1).append("x").toString();
            String s3 = (new StringBuilder()).append("x").append(s1.trim()).append("x").toString();
            Rect rect = new Rect();
            Rect rect1 = new Rect();
            Rect rect2 = new Rect();
            paint.getTextBounds(s1, 0, s1.length(), rect);
            paint.getTextBounds(s2, 0, s2.length(), rect1);
            paint.getTextBounds(s3, 0, s3.length(), rect2);
            i += rect.width() + (rect1.width() - rect2.width());
        }
        Ln.d("TextView width = %d", i);
        return i;
    }

    public static int[] getViewLocation(View view, Activity activity) {
        int[] loc = new int[2];
        view.getLocationOnScreen(loc);
        loc[1] = loc[1] - (getDisplayHeight(view.getContext()) - getContentView(activity).getMeasuredHeight());
        return loc;
    }

    public static void linkify(TextView textview) {
        Linkify.addLinks(textview, Linkify.WEB_URLS);
    }

    public static int roundUp(float f) {
        return (int) (0.5f + f);
    }

    public static boolean supportsExtraHighRes(Context context) {
        return context.getResources().getDisplayMetrics().densityDpi > 240;
    }

    public static boolean supportsHighRes(Context context) {
        return context.getResources().getDisplayMetrics().densityDpi > 160;
    }

    public static boolean isViewContains(View view, int rx, int ry) {
        if (view == null) {
            return false;
        }
        int[] l = new int[2];
        view.getLocationOnScreen(l);
        int x = l[0];
        int y = l[1];
        int w = view.getWidth();
        int h = view.getHeight();

        if (rx < x || rx > x + w || ry < y || ry > y + h) {
            return false;
        }
        return true;
    }

    public static void loadXmlAttr(View view, NamedNodeMap attributes, float rate) {
        ViewGroup.LayoutParams params = view.getLayoutParams();
        Context context = view.getContext();
        if (attributes != null && attributes.getLength() > 0) {
            for (int i = 0; i < attributes.getLength(); i++) {
                Node n = attributes.item(i);
                String name = n.getNodeName();
                float value = dipToPx(context, Float.parseFloat(n.getNodeValue()) * rate);
                // Ln.e("n.name = %s, n.value = %s", n.getNodeName(),
                // n.getNodeValue());
                if ("width".equals(name)) {
                    params.width = (int) value;
                } else if ("height".equals(name)) {
                    params.height = (int) value;
                } else if ("padding".equals(name)) {
                    int padding = (int) value;
                    view.setPadding(padding, padding, padding, padding);
                } else if ("padding_left".equals(name)) {
                    view.setPadding((int) value, view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom());
                } else if ("padding_right".equals(name)) {
                    view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), (int) value, view.getPaddingBottom());
                } else if ("margin_top".equals(name)) {
                    ((ViewGroup.MarginLayoutParams) params).topMargin = (int) value;
                } else if ("margin_right".equals(name)) {
                    ((ViewGroup.MarginLayoutParams) params).rightMargin = (int) value;
                } else if ("margin_left".equals(name)) {
                    ((ViewGroup.MarginLayoutParams) params).leftMargin = (int) value;
                } else if ("margin_bottom".equals(name)) {
                    ((ViewGroup.MarginLayoutParams) params).bottomMargin = (int) value;
                } else if ("text_size".equals(name)) {
                    if (view instanceof TextView) {
                        ((TextView) view).setTextSize(Float.parseFloat(n.getNodeValue()) * rate);
                    }
                }
            }
        }
    }

    /**
     * 图片缩放
     *
     * @param drawable
     * @param w
     * @param h
     * @return
     */
    public static Drawable zoomDrawable(Drawable drawable, int w, int h) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap oldbmp = drawableToBitmap(drawable);
        Matrix matrix = new Matrix();
        float scaleWidth = ((float) w / width);
        float scaleHeight = ((float) h / height);
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true);
        return new BitmapDrawable(null, newbmp);
    }

    private static Bitmap drawableToBitmap(Drawable drawable) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
        Bitmap bitmap = Bitmap.createBitmap(width, height, config);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);
        return bitmap;
    }

    public static Drawable getDrawableBySize(Context context, Drawable d, int width, int height) {
        try {
            if (d != null && d instanceof BitmapDrawable) {
                Bitmap b = ((BitmapDrawable) d).getBitmap();
                Bitmap r = Bitmap.createScaledBitmap(b, width, height, true);
                return new BitmapDrawable(context.getResources(), r);
            }
        } catch (Exception e) {
            Ln.e(e);
        }
        return null;
    }

    public static Bitmap buildBitmapBySize(Resources res, int resId, int w, int h) {
        Bitmap srcBitmap = BitmapFactory.decodeResource(res, resId);
        float width = srcBitmap.getWidth();
        float height = srcBitmap.getHeight();
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) w) / width;
        float scaleHeight = ((float) h) / height;
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(srcBitmap, 0, 0, (int) width, (int) height, matrix, true);
        if (bitmap != srcBitmap && !srcBitmap.isRecycled()){
            srcBitmap.recycle();
        }
        return bitmap;
    }

    public static Bitmap buildBitmapFromDrawableResIdBySize(Resources res, int resId, int w, int h) {
        Drawable drawable = res.getDrawable(resId);
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
        Bitmap bitmap = Bitmap.createBitmap(w, h, config);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        drawable.draw(canvas);
        return bitmap;
    }

    public static Bitmap getBitmapFromDrawableResId(Resources res, int resId) {
        return drawableToBitmap(res.getDrawable(resId));
    }

    public static boolean isExposedVertical(View view, float aspect) {
        Rect r = new Rect();
        if (view != null && view.getVisibility() == View.VISIBLE) {
            boolean flag = view.getGlobalVisibleRect(r);
            return flag && (aspect <= 0F || ((r.bottom - r.top) * 1.0F / view.getHeight()) >= aspect);
        }
        return false;
    }

    public static boolean isExposedVertical(View view) {
        return isExposedVertical(view, VIEW_EXPOSED_ASPECT);
    }

    public static boolean isExposedHorizontal(View view, float aspect) {
        Rect r = new Rect();
        if (view != null && view.getVisibility() == View.VISIBLE) {
            boolean flag = view.getGlobalVisibleRect(r);
            return flag && (aspect <= 0F || ((r.right - r.left) * 1.0F / view.getWidth()) >= aspect);
        }
        return false;
    }

    public static boolean isExposedHorizontal(View view) {
        return isExposedHorizontal(view, VIEW_EXPOSED_ASPECT);
    }
}
